package com.probox.common.entity.service.wechat.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.probox.common.core.constant.CachePrefix;
import com.probox.common.core.domain.WeChatInfomationCoupon;
import com.probox.common.core.domain.WeChatInfomationOrder;
import com.probox.common.core.domain.WechatInfomation;
import com.probox.common.core.enums.CustomerOperationGiveCouponEnum;
import com.probox.common.core.enums.DataStatus;
import com.probox.common.core.enums.WechatInfomationEnum;
import com.probox.common.core.enums.WechatInformationTypeEnum;
import com.probox.common.core.exception.WechatException;
import com.probox.common.core.utils.SecurityUtils;
import com.probox.common.entity.domain.wechat.WechatAuthorizationInfo;
import com.probox.common.entity.domain.wechat.WechatMessageList;
import com.probox.common.entity.domain.wechat.vo.ValueVo;
import com.probox.common.entity.domain.wechat.vo.WechatInfomationReturnDataVo;
import com.probox.common.entity.domain.wechat.vo.WechatInfomationReturnVo;
import com.probox.common.entity.mapper.wechat.WechatAuthorizationInfoMapper;
import com.probox.common.entity.service.customer.ICustomerInfoAccountService;
import com.probox.common.entity.service.wechat.IWechatMessageListService;
import com.probox.common.entity.service.wechat.WechatInformationService;
import com.probox.common.entity.service.wechat.WechatMiniService;
import com.probox.common.entity.utils.HttpUtil;
import com.probox.common.entity.utils.WeChatRequest;
import com.probox.common.redis.service.RedisService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/WechatInformationService")
public class WechatInformationServiceImpl implements WechatInformationService {

    @Autowired
    private WechatMiniService wechatMiniService;

    @Autowired
    private IWechatMessageListService wechatMessageListService;

    @Autowired
    private ICustomerInfoAccountService iCustomerInfoAccountService;

    //授权信息对象Mapper
    @Autowired
    private WechatAuthorizationInfoMapper authorizationInfoMapper;

    @Autowired
    private RedisService redisService;

    private final String applet = "applet";

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final String SEND_MESSAGE_SERVICE = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";

    private static final String INFORMATION_TEMPLATE = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=";


    /**
     * 查询消息模板接口
     *
     * @return
     */
    @Override
    public List<String> getTemplateList() {
        WechatInfomationReturnVo template = getTemplate(SecurityUtils.getCustomerPlatformUid());
        if (template.getData() == null || template.getData().size() == 0) {
            return new ArrayList<>();
        }
        List<WechatInfomationReturnDataVo> data = template.getData();
        List<String> collect = data.stream().map(WechatInfomationReturnDataVo::getPriTmplId).collect(Collectors.toList());
        return collect;
    }


    /**
     * 获取当前帐号下的个人模板列表
     *
     * @return
     */
    public WechatInfomationReturnVo getTemplate(String token, Long platformUid) {
        String key = CachePrefix.WECHAT_INFORMATION_AUTHORIZATION + platformUid;
        WechatInfomationReturnVo wechatInfomationReturnVo = redisService.get(key, WechatInfomationReturnVo.class);
        logger.info("读取缓存中的个人模板：{}", wechatInfomationReturnVo);
        if (wechatInfomationReturnVo == null) {
            String url = INFORMATION_TEMPLATE + token;
            WeChatRequest weChatRequest = new WeChatRequest();
            logger.info("获取获取当前帐号下的个人模板列表请求参数：{}", url);
            logger.info("-----------------------------------");
            String data = weChatRequest.weChatGet(url);
            JSONObject jsonObject = JSONObject.parseObject(data);
            logger.info("获取获取当前帐号下的个人模板列表返回结果：{}", jsonObject);
            logger.info("-----------------------------------");
            wechatInfomationReturnVo = JSON.parseObject(data, WechatInfomationReturnVo.class);
            redisService.set(key, wechatInfomationReturnVo, Long.decode("60"), TimeUnit.MINUTES);
        }
        return wechatInfomationReturnVo;
    }


    /**
     * 发送小程序模板消息
     *
     * @param wechatInfomation
     * @return
     */
    @Override
    public Boolean pushInformation(WechatInfomation wechatInfomation, Long platformUid) {
        logger.info("-----------------开始处理微信消息----------平台Id{}", platformUid);
        String key = CachePrefix.PLATFORM_AUTHORIZER_APPID + platformUid + "_" + applet;
        Object authorizerappid = redisService.getCacheObject(key);
        WechatAuthorizationInfo wechatAuthorizationInfo = authorizationInfoMapper.selectById(String.valueOf(authorizerappid));
        if (authorizerappid != null) {
            if (DataStatus.delete.getKey().equals(wechatAuthorizationInfo.getDataStatus())) {
                throw new WechatException("请授权后重试");
            }
        } else {
            wechatAuthorizationInfo = wechatMiniService.PlatformRefreshToken(applet, String.valueOf(platformUid));
        }
        String token = wechatAuthorizationInfo.getAuthorizerAccessToken();
        logger.info("-----------------获得Token----------{}", token);
        String url = SEND_MESSAGE_SERVICE + token;
        JSONObject json = new JSONObject();
        json.put("touser", wechatInfomation.getTouser());
        json.put("page", wechatInfomation.getPage());
        json.put("lang", wechatInfomation.getLang());
        JSONObject jsonObject = structureData(wechatInfomation, token, platformUid);
        if (jsonObject != null) {
            json.put("template_id", jsonObject.getString("priTmplId"));
            wechatInfomation.setTemplateId(jsonObject.getString("priTmplId"));
            json.put("data", jsonObject.get("data"));
            logger.info("发送小程序模板消息请求参数：{}", json);
            logger.info("-----------------------------------");
            String data = HttpUtil.PostUrl(url, json);
            logger.info("发送小程序模板消息返回结果：{}", data);
            logger.info("-----------------------------------");
            record(wechatInfomation, json, data, platformUid);
        }
        return true;
    }

    /**
     * 记录发送消息记录
     *
     * @return
     */
    public Boolean record(WechatInfomation wechatInfomation, JSONObject jsonObject, String data, Long platformUid) {
        WechatMessageList wechatMessageList = new WechatMessageList();
        if (WechatInfomationEnum.newOrder.getValue().equals(wechatInfomation.getInfomationType()) || WechatInfomationEnum.cancelOrder.getValue().equals(wechatInfomation.getInfomationType()) || WechatInfomationEnum.shipmentsOrder.getValue().equals(wechatInfomation.getInfomationType())) {
            ObjectMapper objectMapper = new ObjectMapper();
            WeChatInfomationOrder weChatInfomationOrder = objectMapper.convertValue(wechatInfomation.getData(), WeChatInfomationOrder.class);
            wechatMessageList.setPlatformUid(platformUid);
            wechatMessageList.setTemplateNo(wechatInfomation.getTemplateId());
            wechatMessageList.setTemplateTitle(wechatInfomation.getInfomationType());
            wechatMessageList.setBizNo(weChatInfomationOrder.getOrderNo());
            wechatMessageList.setSendTime(new Date());
            wechatMessageList.setMessageBody(jsonObject.toJSONString());
            wechatMessageList.setMessageResult(data);

            HashMap hashMap = iCustomerInfoAccountService.getCustomerInfoByOpenId(wechatInfomation.getTouser());
            wechatMessageList.setMemberOpenId(wechatInfomation.getTouser());
            wechatMessageList.setMemberUid(Long.parseLong(hashMap.get("customerUid").toString()));
            wechatMessageList.setMemberNickName(hashMap.get("accountNickName").toString());
            jsonObject = JSONObject.parseObject(data);
            wechatMessageList.setSendStatus(jsonObject.getString("errcode"));

            wechatMessageListService.save(wechatMessageList);
        }
        return true;

    }


    /**
     * 构建模板消息Data对象
     */
    public JSONObject structureData(WechatInfomation wechatInfomation, String token, Long platformUid) {
        HashMap hashMap = new HashMap();
        WechatInfomationReturnVo template = getTemplate(token, platformUid);
        logger.info("推送消息：{}", wechatInfomation);
        logger.info("模板信息：{}", template);
        WechatInfomationReturnDataVo wechatInfomationReturnDataVo = template.getData().stream().filter(o -> o.getTitle().equals(wechatInfomation.getInfomationType())).findAny().orElse(null);
        if (wechatInfomationReturnDataVo == null) {
            logger.info("未找到小程序消息模板");
            return null;
        }
        String content = wechatInfomationReturnDataVo.getContent();
        if (WechatInfomationEnum.newOrder.getValue().equals(wechatInfomation.getInfomationType()) || WechatInfomationEnum.cancelOrder.getValue().equals(wechatInfomation.getInfomationType()) || WechatInfomationEnum.shipmentsOrder.getValue().equals(wechatInfomation.getInfomationType())) {
            ObjectMapper objectMapper = new ObjectMapper();
            WeChatInfomationOrder weChatInfomationOrder = objectMapper.convertValue(wechatInfomation.getData(), WeChatInfomationOrder.class);
            String[] analysisType = analysisType(content);
            String[] analysisMsg = analysisMsg(content);
            for (int i = 0; i < analysisType.length; i++) {
                if (WechatInformationTypeEnum.createTime.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getCreateTime()));
                }
                if (WechatInformationTypeEnum.cancelTime.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getCancelTime()));
                }
                if (WechatInformationTypeEnum.deliverTime.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getDeliverTime()));
                }
                if (WechatInformationTypeEnum.consigneeName.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getConsigneeName()));
                }
                if (WechatInformationTypeEnum.orderNo.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getOrderNo()));
                }
                if (WechatInformationTypeEnum.orderNoStr.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getOrderNo()));
                }
                if (WechatInformationTypeEnum.orderMoney.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getOrderMoney()));
                }
                if (WechatInformationTypeEnum.expressNo.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getExpressNo()));
                }
                if (WechatInformationTypeEnum.proName.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(cutName(weChatInfomationOrder.getProName(), 20)));
                }
                if (WechatInformationTypeEnum.remark.getValue().equals(analysisType[i])) {
                    if (weChatInfomationOrder.getRemark() == null || weChatInfomationOrder.getRemark().equals("")) {
                        weChatInfomationOrder.setRemark("订单已取消");
                    }
                    hashMap.put(analysisMsg[i], new ValueVo(cutName(weChatInfomationOrder.getRemark(), 20)));
                }
                if (WechatInformationTypeEnum.expressCompany.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationOrder.getExpressCompany()));
                }
                if (WechatInformationTypeEnum.warmPrompt.getValue().equals(analysisType[i])) {
                    if (weChatInfomationOrder.getRemark() == null || weChatInfomationOrder.getRemark().equals("")) {
                        weChatInfomationOrder.setRemark("订单已取消");
                    }
                    hashMap.put(analysisMsg[i], new ValueVo(cutName(weChatInfomationOrder.getRemark(), 20)));
                }
            }
        }
        if (WechatInfomationEnum.sendCoupon.getValue().equals(wechatInfomation.getInfomationType())) {
            ObjectMapper objectMapper = new ObjectMapper();
            WeChatInfomationCoupon weChatInfomationCoupon = objectMapper.convertValue(wechatInfomation.getData(), WeChatInfomationCoupon.class);
            String[] analysisType = analysisType(content);
            String[] analysisMsg = analysisMsg(content);
            for (int i = 0; i < analysisType.length; i++) {
                if (CustomerOperationGiveCouponEnum.couponName.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationCoupon.getCouponName()));
                }
                if (CustomerOperationGiveCouponEnum.couponType.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationCoupon.getCouponType()));
                }
                if (CustomerOperationGiveCouponEnum.gainTime.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationCoupon.getGainTime()));
                }
                if (CustomerOperationGiveCouponEnum.expiresTime.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationCoupon.getExpiresTime()));
                }
                if (CustomerOperationGiveCouponEnum.couponNumber.getValue().equals(analysisType[i])) {
                    hashMap.put(analysisMsg[i], new ValueVo(weChatInfomationCoupon.getCouponNumber()));
                }
            }
        }
        JSONObject data = new JSONObject();
        data.put("priTmplId", wechatInfomationReturnDataVo.getPriTmplId());
        data.put("data", hashMap);
        logger.info("构建的发送消息内容：{}", data);
        return data;
    }


    /**
     * 解析微信模板分类
     *
     * @param smg
     * @return
     */
    public static String[] analysisType(String smg) {
        String[] split = smg.split(":");
        String[] output = StringUtils.substringsBetween(smg, "\n", ":");

        String[] smgType = new String[output.length + 1];
        for (int i = 0; i < output.length; i++) {
            if (i == 0) {
                smgType[0] = split[0];
            }
            smgType[i + 1] = output[i];
        }
        return smgType;
    }

    /**
     * 解析微信模板消息参数
     *
     * @param smg
     * @return
     */
    public static String[] analysisMsg(String smg) {
        String[] output = StringUtils.substringsBetween(smg, "{{", ".DATA}}");
        return output;
    }


    /**
     * 截取字符串
     *
     * @param msg
     * @return
     */
    public static String cutName(String msg, Integer number) {
        if (msg.length() > number) {
            return msg.substring(0, number);
        }
        return msg;
    }

    /**
     * 获取当前帐号下的个人模板列表 对外接口
     *
     * @return
     */
    public WechatInfomationReturnVo getTemplate(Long platform) {
        String key = CachePrefix.WECHAT_INFORMATION_AUTHORIZATION + platform;
        WechatInfomationReturnVo wechatInfomationReturnVo = redisService.get(key, WechatInfomationReturnVo.class);
        if (wechatInfomationReturnVo == null) {

            String token = CachePrefix.PLATFORM_AUTHORIZER_APPID + platform + "_" + applet;
            Object authorizerappid = redisService.getCacheObject(token);
            WechatAuthorizationInfo wechatAuthorizationInfo = authorizationInfoMapper.selectById(String.valueOf(authorizerappid));
            if (authorizerappid != null) {
                if ("-1".equals(wechatAuthorizationInfo.getDataStatus())) {
                    throw new WechatException("请授权后重试");
                }
            } else {
                wechatAuthorizationInfo = wechatMiniService.PlatformRefreshToken(applet, String.valueOf(platform));
            }

            String url = INFORMATION_TEMPLATE + wechatAuthorizationInfo.getAuthorizerAccessToken();
            WeChatRequest weChatRequest = new WeChatRequest();
            logger.info("获取获取当前帐号下的个人模板列表请求参数：{}", url);
            logger.info("-----------------------------------");
            String data = weChatRequest.weChatGet(url);
            JSONObject jsonObject = JSONObject.parseObject(data);
            logger.info("获取获取当前帐号下的个人模板列表返回结果：{}", jsonObject);
            logger.info("-----------------------------------");
            wechatInfomationReturnVo = JSON.parseObject(data, WechatInfomationReturnVo.class);
            redisService.set(key, wechatInfomationReturnVo, Long.decode("60"), TimeUnit.MINUTES);
        }
        return wechatInfomationReturnVo;
    }


}
